package com.ruoyi.heytalk.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ruoyi.common.annotation.DataSource;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.heytalk.CommonConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.heytalk.ImUser;
import com.ruoyi.common.core.domain.heytalk.dto.LoginDTO;
import com.ruoyi.common.core.domain.heytalk.dto.RegisterDTO;
import com.ruoyi.common.core.domain.heytalk.vo.LoginImUser;
import com.ruoyi.common.core.service.HeyTalkTokenService;
import com.ruoyi.common.enums.DataSourceType;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.RedisUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.heytalk.service.IImUserService;
import com.ruoyi.heytalk.service.LoginService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

/**
 * @author zhusy
 * @since 2021/10/28
 */
@Slf4j
@Service
@DataSource(value = DataSourceType.SLAVE)
public class LoginServiceImpl implements LoginService {

    @Resource
    private IImUserService imUserService;

    @Resource
    private HeyTalkTokenService tokenService;

    @Override
    public AjaxResult<Object> login(LoginDTO loginDTO) {
        try {
            //校验验证码
            //validateCaptcha(loginDTO.getCode(), loginDTO.getUuid());
            ImUser imUser = imUserService.getOne(new LambdaQueryWrapper<ImUser>().eq(ImUser::getUserName, loginDTO.getUserName()));
            if (Objects.isNull(imUser) || !SecurityUtils.matchesPassword(loginDTO.getPassword(), imUser.getPassword())) {
                return AjaxResult.error(MessageUtils.message("heyTalk.user.password.not.match", loginDTO.getUserName()), null);
            }
            if (Objects.equals(CommonConstants.UserStatusEnum.NORMAL.getCode(), imUser.getStatus())) {
                return AjaxResult.error(MessageUtils.message("heyTalk.user.disable", loginDTO.getUserName()), null);
            }
            Map<String,Object> ajax = new HashMap<>(1);
            ajax.put(Constants.TOKEN, tokenService.createToken(createLoginImUser(imUser)));
            ajax.put(CommonConstants.USER_ID, imUser.getId());
            return AjaxResult.success(ajax);
        } catch (Exception e) {
            log.error("登录失败:{}", e);
            throw new ServiceException(MessageUtils.message("heyTalk.user.login.err"));
        }
    }

    @Override
    @Transactional
    public AjaxResult<Void> register(RegisterDTO registerDTO) {
        try {
            //校验验证码
            //validateCaptcha(registerDTO.getCode(), registerDTO.getUuid());
            if (CommonConstants.NOT_UNIQUE.equals(imUserService.checkUserNameUnique(null, registerDTO.getUserName()))) {
                return AjaxResult.error(MessageUtils.message("heyTalk.user.register.username.exist"));
            }
            ImUser imUser = ImUser.builder().build();
            BeanUtil.copyProperties(registerDTO, imUser);
            //密码加密
            imUser.setPassword(SecurityUtils.encryptPassword(registerDTO.getPassword()));
            imUser.setStatus(CommonConstants.UserStatusEnum.DEACTIVATE.getCode());
            return imUserService.save(imUser) ? AjaxResult.success() : AjaxResult.error();
        } catch (Exception e) {
            log.error("注册失败:{}", e);
            throw new ServiceException(MessageUtils.message("heyTalk.user.register.err"));
        }
    }

    @Override
    public AjaxResult<Void> logout() {
        HttpServletRequest request = ServletUtils.getRequest();
        LoginImUser loginImUser = tokenService.getLoginImUser(request);
        if (!Objects.isNull(loginImUser)) {
            tokenService.delLoginImUser(loginImUser.getToken());
        }
        return AjaxResult.success(MessageUtils.message("heyTalk.user.logout.success"));
    }

    /**
     * 创建包装登录对象
     * @param imUser 用户信息
     * @return 包装登录对象
     */
    private LoginImUser createLoginImUser(ImUser imUser) {
        return new LoginImUser(imUser.getId(), imUser);
    }

    /**
     * 校验验证码
     * @param code 验证码
     * @param uuid 唯一标识
     */
    private void validateCaptcha(String code, String uuid) {
        String captcha = RedisUtils.getCacheObject(Constants.CAPTCHA_CODE_KEY + uuid);
        RedisUtils.deleteObject(Constants.CAPTCHA_CODE_KEY + uuid);
        if (captcha == null) {
            throw new CaptchaExpireException();
        }
        if (!code.equalsIgnoreCase(captcha)) {
            throw new CaptchaException();
        }
    }

}
